-- --------------------------------
-- Nothing reloadable on this file yet
-- --------------------------------

local debug = true

assert(type(lantern) == "table")

-- -------- helper functions --------
local function tablecopy(obj)
	if type(obj) ~= "table" then
		return obj
	end

	local tbl = {}
	for k, v in pairs(obj) do
		if type(v) == "table" then
			tbl[k] = tablecopy(v)
		else
			tbl[k] = v
		end
	end
	return tbl
end


-- lantern
lantern.selbox = {
	type = "fixed",
	fixed = {-2.5/16, -8/16, -2.5/16, 2.5/16, 0/16, 2.5/16}
}

lantern.selbox_wall = {
	type = "fixed",
	fixed = {-2.5/16, -8/16, -4/16, 2.5/16, -2.5/16, 4/16}
}

lantern.tileanim = {
	name = "box_lantern_anim.png",
	animation = {type="vertical_frames", length=1.5}
}

lantern.tileanim_dim = {
	name = "box_lantern_anim_dim.png",
	animation = {type="vertical_frames", length=1.5}
}

lantern.generic_def = {
	description = "Lantern",
	paramtype = "light",
	light_source = lantern.bright_full,
	drawtype = "mesh",
	mesh = "box_lantern_floor.obj",
	tiles = {lantern.tileanim},
	selection_box = lantern.selbox,
	paramtype2 = "wallmounted",
	groups = {level=0, dig_immediate=2, attached_node=1, has_flame=1},
	walkable = false,
	is_ground_content = false,
	-- no fixed functions
	on_construct = function(...)
		return lantern.do_construct(...)
	end,
	after_dig_node = function(...)
		return lantern.do_after_dig_node(...)
	end,
	on_place = function(...)
		return lantern.do_place(...)
	end,
	on_punch = function(...)
		return lantern.do_punch(...)
	end,
	on_rightclick = function(...)
		return lantern.do_rightclick(...)
	end,
	on_timer = function(...)
		return lantern.do_timer(...)
	end
}

-- ======== REGISTER ========
function lantern.register()
	if debug then
		minetest.log("action", "[lantern] registering lanterns.")
	end
	-- {"on", "med", "dim", "off"}
	local astate = {"on", "med", "dim", "off"}
	local aside = {"floor", "ceiling", "wall"}

	local def
	local nodename
	for i, side in ipairs(aside) do
		for j, state in ipairs(astate) do
			def = tablecopy(lantern.generic_def)
			nodename = "lantern:lantern"
			if side == "floor" then
				nodename = nodename .. "_floor"
			elseif side == "ceiling" then
				nodename = nodename .. "_ceiling"
				def.mesh = "box_lantern_ceiling.obj"
			elseif side == "wall" then
				nodename = nodename .. "_wall"
				def.mesh = "box_lantern_wall.obj"
				def.selection_box = lantern.selbox_wall
			end
			if state == "on" then
				nodename = nodename .. "_on"
				def.light_source = lantern.bright_full
				def.inventory_image = "box_lantern_inv.png"
				def.wield_image = "box_lantern_inv.png"
				def.groups.not_in_creative_inventory = 1
				def.drop = "lantern:lantern_floor_off"
			elseif state == "med" then
				nodename = nodename .. "_med"
				def.light_source = lantern.bright_med
				-- def.tiles -- same as full bright
				def.groups.not_in_creative_inventory = 1
				def.drop = "lantern:lantern_floor_off"
			elseif state == "dim" then
				nodename = nodename .. "_dim"
				def.light_source = lantern.bright_dim
				def.tiles = {lantern.tileanim_dim}
				-- def.inventory_image = "box_lantern_dim_inv.png"
				-- def.wield_image = "box_lantern_dim_inv.png"
				def.groups.not_in_creative_inventory = 1
				def.drop = "lantern:lantern_floor_off"
			elseif state == "off" then
				nodename = nodename .. "_off"
				def.description = "Lantern (off)"
				def.light_source = lantern.bright_off
				def.tiles = {"box_lantern_off.png"}
				def.inventory_image = "box_lantern_off_inv.png"
				-- to check if it can spread flames when broken }:)
				def.groups.has_flame = 0
				if side == "floor" then
					def.groups.not_in_creative_inventory = 0
				else
					def.groups.not_in_creative_inventory = 1
				end
				def.drop = "lantern:lantern_floor_off"
			end
			if debug then
				minetest.log("action", "[lantern] registering " .. nodename)
			end
			minetest.register_node(nodename, def)
		end
	end

	local gameid = Settings(minetest.get_worldpath() .. DIR_DELIM ..
			'world.mt'):get('gameid')

	if gameid == "minetest" then
		-- expected minetest_game
		-- check if vessels and farming mods are installed
		local isVessels = minetest.get_modpath("vessels")
		local isFarming = minetest.get_modpath("farming")
		local isBasicMaterials = minetest.get_modpath("basic_materials")

		if isBasicMaterials then
			if debug then
				print("[lantern] basic_materials detected SUCCESS!")
			end
			lantern.fuel = "basic_materials:oil_extract"
		end
	end

	if gameid == "musttest" then
		print("[lantern] musttest game detected!")
		local isPlastic = minetest.get_modpath("plastic")
		if isPlastic then
			print("[lantern] plastic detected SUCCESS!")
			lantern.fuel = "plastic:oil_extract"
		else
			lantern.fuel = "default:coal_lump"
		end
	end

	if isVessels and isFarming then
		minetest.register_craft({
			output = "lantern:lantern_floor_off",
			recipe = {
				{"default:glass"},
				{"farming:string"},
				{"vessels:steel_bottle"}
			}
		})
	else
		minetest.register_craft({
			output = "lantern:lantern_floor_off",
			recipe = {
				{"default:iron_lump"},
				{"default:torch"},
				{"default:iron_lump"}
			}
		})
	end
	lantern.abm()
end

function lantern.abm()
--[[
	"lantern:lantern_floor_on",
	"lantern:lantern_floor_med",
	"lantern:lantern_floor_dim",
	"lantern:lantern_floor_off",
	"lantern:lantern_ceiling_on",
	"lantern:lantern_ceiling_med",
	"lantern:lantern_ceiling_dim",
	"lantern:lantern_ceiling_off",
	"lantern:lantern_wall_on",
	"lantern:lantern_wall_med",
	"lantern:lantern_wall_dim",
	"lantern:lantern_wall_off"
--]]
	local update_nodes = {
		"lantern:lantern_floor_on",
		"lantern:lantern_floor_med",
		"lantern:lantern_floor_dim",
		"lantern:lantern_ceiling_on",
		"lantern:lantern_ceiling_med",
		"lantern:lantern_ceiling_dim",
		"lantern:lantern_wall_on",
		"lantern:lantern_wall_med",
		"lantern:lantern_wall_dim",
	}

	-- This ABM is only to update infotext,
	-- it does not affect lamp functionality
	minetest.register_abm({
		nodenames = update_nodes,
		neighbors = {},
		interval = 60,
		chance = 1,
		action = function (pos, node, active_object_count,
				active_object_count_wider)
			lantern.update_info(pos)
		end
	})
end

function lantern.fix()
	-- fix lbm
	minetest.register_lbm({
		label = "Remove _empty lamps",
		name = "lantern:update2",
		nodenames = {
			"lantern:lantern_floor_empty",
			"lantern:lantern_ceiling_empty",
			"lantern:lantern_wall_empty",
			"oillamp:oillamp_wall",
			"oillamp:oillamp_wall_dim",
			"oillamp:oillamp_ceiling",
			"oillamp:oillamp_ceiling_empty",
			"oillamp:oillamp_floor"
			},
		run_at_every_load = true,
		action = function(pos, node)
			node.name = "lantern:lantern_floor_off"
			print("[lantern] removing empty lanterns")
			minetest.swap_node(pos, node)
		end
	})
end

